#ifndef PLOT_WIDGET_H
#define PLOT_WIDGET_H

/**
 * @file PlotWidget.h
 */

#include "ImagePlot.h"
#include "ColourMap.h"

#include "PlotPicker.h"
#include "PlotMagnifier.h"
#include "PlotZoomer.h"
#include "PlotPanner.h"

#include <QtCore/QObject>
#include <QtCore/QString>

#include <qwt_plot.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_grid.h>
#include <qwt_scale_widget.h>

#include <complex>
#include <vector>

using std::vector;

class QMenu;
class QAction;
class QwtScaleWidget;

namespace spectrum {

/**
 * @class PlotWidget
 *
 * @brief
 *
 * @details
 */

class PlotWidget : public QwtPlot
{
    Q_OBJECT

    public:
        /// Constructs a plot handler object
        PlotWidget(QWidget * parent = 0);

        /// Destroys a plot handler object
        virtual ~PlotWidget();

    public:
        /// Clear the plot Canvas
        void clear();

    public slots:
        /// Set the plot title
        void setPlotTitle(const QString&);

        /// Sets the x axis label
        void setXLabel(const QString&);

        /// Set the x label via a input pop-up.
        void menuSetXLabel();

        /// Set the y label via a input pop-up.
        void menuSetYLabel();

        /// Sets the y axis label
        void setYLabel(const QString&);

        /// Sets the scale label.
        void setScaleLabel(const QString&);

        /// Point selected
        void slotSelectedPoint(const QPoint&);

        /// Rectangle selected
        //void slotSelectedRect(const QwtDoubleRect&);

        /// Set the menu title
        void menuSetTitle();

        /// Sets the state of axis visibility
        void setAxesVisible(int state);

        /// Show the plot grid.
        void showGrid(bool);

        /// Show minor grid ticks.
        void showGridMinorTicks(bool);

        /// Toggle the grid on and off.
        void toggleGrid();

        /// Toggle minor grid ticks.
        void toggleGridMinorTicks();

        /// Save the plot widget as a PNG image
        void savePNG(QString fileName = "", unsigned sizeX = 500,
                unsigned sizeY = 500);

        /// Save the plot widget as a PDF.
        void savePDF(QString fileName = "", unsigned sizeX = 500,
                unsigned sizeY = 500);

        /// Update the zoom base.
        void updateZoomBase();

        /// Set the picker selection type
        void rectangleSelect(bool enable = true);

        /// Set the colour scale object
        void enableColourScale(bool on = true);

        /// Toggle plot panning.
        void togglePanner(bool);

        /// Toggle plot zooming.
        void toggleZoomer(bool);

        /// Toggle plot position tracking.
        void togglePicker(bool);

    signals:
        /// Signal emitted when plot title changes
        void titleChanged(const QString&);

        /// Signal emitted when the x axis label changes
        void xLabelChanged(const QString&);

        /// Signal emitted when the y axis label changes
        void yLabelChanged(const QString&);

        /// Signal emitted when the y axis label changes
        void scaleLabelChanged(const QString&);

        /// Emitted when grid is enabled
        void gridEnabled(bool);

        /// Signal for toggle showing minor grid ticks
        void gridMinorTicks(bool);

        /// Signal for toggle showing plot axes
        void axesVisible(bool);

        /// Signal emitted on a picker selection rectangle event
        void xLeftChanged(double);

        /// Signal emitted on a picker selection rectangle event
        void xRightChanged(double);

        /// Signal emitted on a picker selection rectangle event
        void yBottomChanged(double);

        /// Signal emitted on a picker selection rectangle event
        void yTopChanged(double);

    protected:
        /// Function to handle mouse press events.
        void mousePressEvent(QMouseEvent*);

        /// Function to handle mouse move events.
        void mouseMoveEvent(QMouseEvent*);

        /// Function to handle mouse release events.
        void mouseReleaseEvent(QMouseEvent*);

        /// Function to handle key presses.
        void keyPressEvent(QKeyEvent*);

    private:
        /// Set the plot grid object
        void _setGrid();

        /// Set the plot panning object
        void _setPanner();

        /// Setup the Zoomer.
        void _setZoomer();

        /// Setup signal and slot connections
        void _connectSignalsAndSlots();

    private:
        ColourMap _colourMap;

        bool _adjustingColours;
        int _oldx;
        int _oldy;

        PlotPicker _picker;
        PlotPanner _panner;
        PlotZoomer _zoomer;
        PlotMagnifier _magnifier;

        QwtScaleWidget _scale;

        QwtPlotGrid _grid;       // Grid plot item.
};

} // namespace spectrum
#endif // PLOT_WIDGET_H
